#include "STM32server.h"

char buffer[BUFFER_SIZE];
int tcpconnect_flag = 0;

pthread_mutex_t lock;
void *create_shared_memory(int *shm_fd,const char *pathname,const int keyid )
{
   //生成key值
   key_t key = ftok(pathname,keyid);
   if(key == -1){
      perror("ftok");
      return NULL;
   }
   //printf("key = %d\n",key);
   // 创建或打开共享内存对象
   *shm_fd = shmget(key, BUFFER_SIZE, IPC_CREAT|0666);
    if (*shm_fd == -1) {
        perror("shmget");
        return NULL;
    }
    // 映射共享内存
    void *shm_ptr = shmat(*shm_fd,NULL, 0);
    if (shm_ptr ==  (void*)-1) {
        perror("shmat");
        close(*shm_fd);
        return NULL;
    }
    return shm_ptr;

}

/*通过子线程进行连接 */
void *handle_client(void *arg) {
    int client_socket = *((int *)arg);
    free(arg);  // 释放传递过来的指针内存
    int read_value;
    char test_buffer[13];
    int write_times = 3;
 
    /*共享内存 */
   int QT_shm_fd,ali_shm_fd;
   void *QT_shm_ptr,*temp_QT_ptr;
   void *ali_shm_ptr,*temp_ali_ptr;

   QT_shm_ptr = create_shared_memory(&QT_shm_fd,QT_KEY_PATHNAME,QT_KEY_ID);//创建QT端共享内存
   ali_shm_ptr = create_shared_memory(&ali_shm_fd,ALI_KEY_PATHNAME,ALI_KEY_ID);//创建阿里端共享内存

    while ((read_value = read(client_socket, buffer, BUFFER_SIZE - 1)) > 0) {
        buffer[read_value] = '\0';
        //printf("Received from client: %s\n", buffer);
         temp_QT_ptr = QT_shm_ptr;
         temp_ali_ptr = ali_shm_ptr;
         strcpy(temp_QT_ptr,buffer);
         strcpy(temp_ali_ptr,buffer);
         if(write_times >= -1){
            memset(test_buffer,'\0',13);
            sprintf(test_buffer,"{\"LED1\":%d}",!write_times);
            buffer[12] = '\0';
            write(client_socket,test_buffer,13);
            write_times--;
            if(write_times < 0){
                tcpconnect_flag = 1;//tcp连接标志位置1
                pthread_mutex_unlock(&lock);//连接成功后解锁
            }
         }
    }
 
    if (read_value == 0) {
        printf("Client disconnected\n");
    } else if (read_value < 0 && errno != EINTR) {
        perror("read error");
    }
    pthread_mutex_lock(&lock);//断开连接后重新上锁
    close(client_socket);
    //printf("Client socket closed\n");
    pthread_exit(NULL);
}

int STM32_TCP_server(int *tcp_connectsocketfd,int *tcp_acceptsocketfd )
{
	*tcp_connectsocketfd = -1;
	*tcp_acceptsocketfd = -1;
	struct sockaddr_in servaddr, cliaddr;
   socklen_t clilen = sizeof(cliaddr);
   pthread_t tid;
	int ret = 0;

   *tcp_connectsocketfd = socket(AF_INET,SOCK_STREAM,0);

   bzero(&servaddr,sizeof(servaddr)); 
   //memset(&servaddr,0,sizeof(servaddr));
   servaddr.sin_family = AF_INET;
   servaddr.sin_port = htons(PORT);
   inet_aton("IP_ADDRESS",&servaddr.sin_addr);

   ret = bind(*tcp_connectsocketfd,(struct sockaddr *)&servaddr,sizeof(servaddr));

   ret += listen(*tcp_connectsocketfd,9);
   if(ret)
   {
        printf("bind or listen failed\n");
        return -1;
   }
   while (1) {
        *tcp_acceptsocketfd = accept(*tcp_connectsocketfd, (struct sockaddr *)&cliaddr, &clilen);
        if (*tcp_acceptsocketfd < 0) { 
            if (errno == EINTR) {
                continue;
            } else {
                perror("accept error");
                close(*tcp_connectsocketfd);
                exit(EXIT_FAILURE);
            }
        }
        int *client_socket_ptr = malloc(sizeof(int));
        if (!client_socket_ptr) {
            perror("malloc error");
            close(*tcp_acceptsocketfd);
            continue;
        }
        *client_socket_ptr = *tcp_acceptsocketfd;
 
        if (pthread_create(&tid, NULL, handle_client, (void*)client_socket_ptr) != 0) {
            perror("pthread_create error");
            free(client_socket_ptr);
            close(*tcp_acceptsocketfd);
            continue;
        }
         queueserver(*tcp_acceptsocketfd,&lock);
        // 分离线程
        pthread_detach(tid);
    }

	return 1;
}


int STM32_server()
{
   /*网络连接套接子 */
   int tcp_connectsocketfd;
   int tcp_acceptsocketfd;

   pthread_mutex_init(&lock, NULL); // 使用默认属性初始化互斥锁

        // TCP网络连接,子线程连接
        pthread_mutex_lock(&lock);//连接时上锁
        if (STM32_TCP_server(&tcp_connectsocketfd, &tcp_acceptsocketfd) != 1) {
            printf("Failed to start TCP server\n");
        }
        // 关闭网络连接
        close(tcp_acceptsocketfd);
        tcp_acceptsocketfd = -1;
        close(tcp_connectsocketfd);
        tcp_connectsocketfd = -1;
 
        printf("Disconnect and wait for new connect\n");
   return 0;
}

int main()
{
   STM32_server();
	return 0;
}
